 /**
 * 混入 也成为多重继承
 * 暂未区分 原型属性和非原型属性
 */

 function maxin( targetObj, source={}, ...keys ){
    if(keys.length){
        for(let i=0;i<keys.length;i++){
            let type = typeof source[keys[i]];
            
            if(type==null||['function','number','boolean','symbol', 'bigint'].includes(type)){
                targetObj[keys[i]] = source[keys[i]]
            }else if(source[keys[i]] instanceof Date){
                targetObj[keys[i]] = new Date(source[keys[i]])
            }else{
                // 深度克隆, JSON.stringfy会忽略 key为Symbol和值为Symbol的属性，也会忽略Function，BigInt在JSON.stringfy会报错
                targetObj[keys[i]] = JSON.stringify( JSON.parse(source[keys[i]]) )
            }
        }
    }else{
        for(let key in source){
            let type = typeof source[key];
            if(type==null||['function','number','boolean','symbol', 'bigint'].includes(type)){
                targetObj[keys] = source[key]
            }else if(source[key] instanceof Date){
                targetObj[keys] = new Date(source[key])
            }else{
                // 深度克隆
                targetObj[keys] = JSON.stringify( JSON.parse(source[keys[i]]) )
            }
        }
    }
 }


 /**
  * JSON.stringify()将值转换为相应的 JSON 格式：

  * 1.转换值如果有 toJSON() 方法，该方法定义什么值将被序列化。
  * 2.非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。
  * 3.布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。
  * 4.undefined、任意的函数以及 symbol 值，在序列化过程中会被忽略（出现在非数组对象的属性值中时）或者被转换成 null（出现在数组中时）。函数、undefined 被单独转换时，会返回 undefined，如JSON.stringify(function(){}) or JSON.stringify(undefined).
  * 5.对包含循环引用的对象（对象之间相互引用，形成无限循环）执行此方法，会抛出错误 (重要)。
  * 6.所有以 symbol 为属性键的属性都会被完全忽略掉，即便 replacer 参数中强制指定包含了它们。
  * 7.Date 日期调用了 toJSON() 将其转换为了 string 字符串（同 Date.toISOString()），因此会被当做字符串处理。
  * 8.NaN 和 Infinity 格式的数值及 null 都会被当做 null。
  * 9.其他类型的对象，包括 Map/Set/WeakMap/WeakSet，仅会序列化可枚举的属性。
  */